﻿/*
输入：
3
1 2
2 3
1 3
输出：
1 3
*/
// N个顶点和边
int N = int.Parse(Console.ReadLine());

// 并查集
int[] father = new int[N+1];
for (int i = 0; i < father.Length; i++) // 初始化
{
    father[i] = i;
}

int find(int[] father, int u) // 搜索根节点，并进行路径压缩
{
    return father[u] == u ? u : father[u] = find(father, father[u]);
}

void Join(int[] father, int u, int v) // 加入集合
{
    u = find(father, u);
    v = find(father, v);
    if (u == v) return;
    father[u] = v;
}

bool isSame(int[] father, int u, int v) // 判断是否在一个集合中
{
    u = find(father, u);
    v = find(father, v);
    return u == v;
}

// 接收输入
for (int i = 0; i < N; i++)
{
    string[] stStr = Console.ReadLine().Split(" ");
    int s = int.Parse(stStr[0]);
    int t = int.Parse(stStr[1]);
    if(isSame(father,s,t)) Console.WriteLine(string.Join(" ", stStr));
    else Join(father,s,t);
}